/**
 * XL-Payment 银联支付适配器
 */
import { formatAmount, delay } from '../utils';

export default class UnionpayAdapter {
  constructor() {
    this.name = 'unionpay';
    this.title = '银联支付';
  }
  
  /**
   * 发起支付
   * @param {Object} options 支付参数
   * @returns {Promise} 支付结果
   */
  async pay(options) {
    const { order, amount, config, env } = options;
    
    try {
      // 处理不同平台的支付方式
      if (env.isH5) {
        // H5支付
        return await this._h5Pay(order, amount, config);
      } else if (env.isApp) {
        // APP支付
        return await this._appPay(order, amount, config);
      } else {
        throw new Error('当前平台不支持银联支付');
      }
    } catch (error) {
      console.error('银联支付失败:', error);
      return { 
        success: false, 
        message: '支付失败: ' + (error.message || error),
        error
      };
    }
  }
  
  /**
   * H5支付
   * @param {Object} order 订单信息
   * @param {Number} amount 支付金额
   * @param {Object} config 配置
   * @returns {Promise} 支付结果
   */
  async _h5Pay(order, amount, config) {
    // 获取H5支付参数
    try {
      // 模拟从服务器获取支付参数
      const payParams = await this._getPayParams({
        order,
        amount,
        config,
        tradeType: 'H5'
      });
      
      if (!payParams || !payParams.success) {
        throw new Error(payParams?.message || '获取支付参数失败');
      }
      
      // 跳转到银联支付页面
      if (payParams.formUrl) {
        // 记录支付状态
        uni.setStorageSync(`unionpay_paying_${order.id}`, JSON.stringify({
          timestamp: Date.now(),
          returnUrl: payParams.returnUrl || location.href
        }));
        
        // 跳转到银联支付
        location.href = payParams.formUrl;
        
        // H5支付是重定向，这里直接返回进行中状态
        return {
          success: true,
          pending: true,
          order,
          paymentType: 'unionpay',
          message: '已跳转到银联支付'
        };
      } else {
        throw new Error('未获取到支付链接');
      }
    } catch (error) {
      console.error('银联H5支付失败:', error);
      return { 
        success: false, 
        message: '支付失败: ' + (error.message || error),
        error
      };
    }
  }
  
  /**
   * APP支付
   * @param {Object} order 订单信息
   * @param {Number} amount 支付金额
   * @param {Object} config 配置
   * @returns {Promise} 支付结果
   */
  async _appPay(order, amount, config) {
    // 获取APP支付参数
    try {
      // 模拟从服务器获取支付参数
      const payParams = await this._getPayParams({
        order,
        amount,
        config,
        tradeType: 'APP'
      });
      
      if (!payParams || !payParams.success) {
        throw new Error(payParams?.message || '获取支付参数失败');
      }
      
      // 调用APP支付
      return new Promise((resolve, reject) => {
        uni.requestPayment({
          provider: 'unionpay',
          orderInfo: payParams.orderInfo, // APP支付参数字符串
          success: result => {
            resolve({
              success: true,
              order,
              result,
              paymentType: 'unionpay',
              message: '支付成功'
            });
          },
          fail: error => {
            // 判断是否为用户取消
            const isCancel = error.errMsg && error.errMsg.indexOf('cancel') > -1;
            resolve({
              success: false,
              canceled: isCancel,
              order,
              error,
              message: isCancel ? '用户取消支付' : '支付失败'
            });
          }
        });
      });
    } catch (error) {
      console.error('银联APP支付失败:', error);
      return { 
        success: false, 
        message: '支付失败: ' + (error.message || error),
        error
      };
    }
  }
  
  /**
   * 模拟获取支付参数
   * @param {Object} options 请求参数
   * @returns {Promise} 支付参数
   */
  async _getPayParams(options) {
    const { order, amount, config, tradeType } = options;
    
    // 模拟网络请求延迟
    await delay(500);
    
    // 在实际项目中，应该调用服务端接口获取支付参数
    // 这里仅作为演示
    
    // 根据支付类型返回对应的参数
    switch (tradeType) {
      case 'H5':
        // H5支付参数
        return {
          success: true,
          formUrl: 'https://gateway.95516.com/gateway/api/frontTransReq.do?' + 
                  'version=5.1.0&encoding=UTF-8&signMethod=01&txnType=01&txnSubType=01&bizType=000201&' +
                  'channelType=07&merId=777290058110097&accessType=0&orderId=' + order.id + '&txnTime=' +
                  new Date().toISOString().replace(/[-:]/g, '').substring(0, 14) + '&txnAmt=' + 
                  (amount * 100).toString() + '&currencyCode=156&frontUrl=' +
                  encodeURIComponent('https://example.com/return'),
          returnUrl: 'https://example.com/return'
        };
        
      case 'APP':
        // APP支付参数
        return {
          success: true,
          orderInfo: 'version=5.1.0&encoding=UTF-8&signMethod=01&txnType=01&txnSubType=01&bizType=000201&' +
                   'channelType=08&merId=777290058110097&accessType=0&orderId=' + order.id + '&txnTime=' +
                   new Date().toISOString().replace(/[-:]/g, '').substring(0, 14) + '&txnAmt=' + 
                   (amount * 100).toString() + '&currencyCode=156&sign=MOCK_SIGN'
        };
        
      default:
        throw new Error('不支持的支付类型');
    }
  }
  
  /**
   * 查询订单
   * @param {Object} options 查询参数
   * @returns {Promise} 查询结果
   */
  async queryOrder(options) {
    const { order, config } = options;
    
    try {
      // 模拟网络请求
      await delay(500);
      
      // 在实际项目中，应该调用服务端接口查询
      // 这里仅作为演示
      
      // 随机返回订单状态
      const status = Math.random() > 0.3 ? 'PAID' : 'PENDING';
      
      return {
        success: true,
        orderId: order.id,
        status,
        message: status === 'PAID' ? '支付成功' : '等待支付',
        paidAt: status === 'PAID' ? new Date().toISOString() : null,
        tradeNo: status === 'PAID' ? 'unionpay_trade_' + Date.now() : null,
        paymentType: 'unionpay'
      };
    } catch (error) {
      console.error('查询银联订单失败:', error);
      return { 
        success: false, 
        message: '查询失败: ' + (error.message || error),
        error,
        orderId: order.id
      };
    }
  }
  
  /**
   * 关闭订单
   * @param {Object} options 关闭参数
   * @returns {Promise} 关闭结果
   */
  async closeOrder(options) {
    const { order, config } = options;
    
    try {
      // 模拟网络请求
      await delay(500);
      
      // 在实际项目中，应该调用服务端接口关闭
      // 这里仅作为演示
      
      return {
        success: true,
        orderId: order.id,
        message: '订单关闭成功',
        closeTime: new Date().toISOString(),
        paymentType: 'unionpay'
      };
    } catch (error) {
      console.error('关闭银联订单失败:', error);
      return { 
        success: false, 
        message: '关闭失败: ' + (error.message || error),
        error,
        orderId: order.id
      };
    }
  }
  
  /**
   * 退款处理
   * @param {Object} options 退款参数
   * @returns {Promise} 退款结果
   */
  async refund(options) {
    const { order, amount, reason, config } = options;
    
    try {
      // 模拟网络请求
      await delay(800);
      
      // 在实际项目中，应该调用服务端接口申请退款
      // 这里仅作为演示
      
      return {
        success: true,
        orderId: order.id,
        refundId: 'unionpay_refund_' + Date.now(),
        refundAmount: amount,
        message: '退款申请成功',
        refundTime: new Date().toISOString(),
        paymentType: 'unionpay'
      };
    } catch (error) {
      console.error('银联退款失败:', error);
      return { 
        success: false, 
        message: '退款失败: ' + (error.message || error),
        error,
        orderId: order.id
      };
    }
  }
} 